/*
 * 文 件 名：PlatException.java
 * 描    述：平台异常基类，所有平台模块子异常均需继承该基类。
 * 修 改 人：zhuou
 * 修改时间：2012-9-12
 * 修改内容：新增
 */
package com.oswift.utils.exception;

import java.io.Serializable;
import java.text.MessageFormat;

import com.oswift.utils.cache.ResourceManager;

/**
 * 
 * 平台异常基类，所有平台模块子异常均需继承该基类。
 * 
 * @author zhuou
 * @version C03 Sep 13, 2012
 * @since OSwift GPM V1.0
 */
public class PlatException extends Exception
{
    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = 1030123567669115158L;

    /**
     * 存储异常的数据Bean
     */
    private ExceptionBean exceptionBean = new ExceptionBean();

    /**
     * 实例化Exception时传入的其他异常
     */
    private Throwable nestedThrowable = null;

    /**
     * 普通构造函数
     */
    public PlatException()
    {
        super();
    }

    /**
     * 封装其他异常为GPMException
     * 
     * @param cause
     *            异常
     */
    public PlatException(Throwable cause)
    {
        super(cause);
        this.nestedThrowable = cause;
    }

    /**
     * 带异常码的构造函数
     * 
     * @param exceptionCode
     *            异常码
     */
    public PlatException(String exceptionCode)
    {
        super();
        exceptionBean.setCode(exceptionCode);
    }

    /**
     * 带异常码和异常描述的构造函数
     * 
     * @param exceptionCode
     *            异常码
     * @param message
     *            异常消息
     */
    public PlatException(String exceptionCode, String message)
    {
        super(message);
        exceptionBean.setCode(exceptionCode);
        exceptionBean.setMessage(message);
    }

    /**
     * 带异常码的构造函数,封装其它异常
     * 
     * @param exceptionCode
     *            异常码
     * @param cause
     *            异常
     */
    public PlatException(String exceptionCode, Throwable cause)
    {
        super(cause);
        exceptionBean.setCode(exceptionCode);
        this.nestedThrowable = cause;
    }

    /**
     * 带异常码、异常描述和异常堆栈的构造函数
     * 
     * @param exceptionCode
     *            异常码
     * @param message
     *            异常消息
     * @param cause
     *            异常
     */
    public PlatException(String exceptionCode, String message, Throwable cause)
    {
        super(message, cause);
        exceptionBean.setCode(exceptionCode);
        exceptionBean.setMessage(message);
        this.nestedThrowable = cause;
    }

    /**
     * 带异常码和异常参数信息的构造函数
     * 
     * @param exceptionCode
     *            异常码
     * @param exceptionArgs
     *            异常参数，不提供国际化
     */
    public PlatException(String exceptionCode, Object exceptionArgs)
    {
        super();
        exceptionBean.setCode(exceptionCode);
        exceptionBean.setParameters(new Object[]
        {exceptionArgs});
    }

    /**
     * 带异常码和一组异常参数的构造函数
     * 
     * @param exceptionCode
     *            异常码
     * @param exceptionArgs
     *            异常参数，不提供国际化
     */
    public PlatException(String exceptionCode, Object[] exceptionArgs)
    {
        super();
        exceptionBean.setCode(exceptionCode);
        exceptionBean.setParameters(exceptionArgs);
    }

    /**
     * 带异常码和一组异常参数的构造函数
     * 
     * @param exceptionCode
     *            异常码
     * @param exceptionArgs
     *            异常参数，不提供国际化
     * @param cause
     *            异常
     */
    public PlatException(String exceptionCode, Object[] exceptionArgs,
            Throwable cause)
    {
        super(cause);
        this.nestedThrowable = cause;
        exceptionBean.setCode(exceptionCode);
        exceptionBean.setParameters(exceptionArgs);
    }

    /**
     * 带异常码和异常参数的构造函数
     * 
     * @param exceptionCode
     *            异常码
     * @param exceptionArg
     *            异常参数，不提供国际化
     * @param cause
     *            异常
     */
    public PlatException(String exceptionCode, Object exceptionArg,
            Throwable cause)
    {
        super(cause);
        this.nestedThrowable = cause;
        exceptionBean.setCode(exceptionCode);
        exceptionBean.setParameters(new Object[]
        {exceptionArg});
    }

    /**
     * 获取异常码
     * 
     * @return 返回相应的异常码
     */
    public String getExceptionCode()
    {
        return exceptionBean.getCode();
    }

    /**
     * 获取异常信息 异常堆栈能够把历史异常打印出来，即异常不能中断，最新发生的异常显示在最前面
     * 
     * @return 返回相应的异常信息
     */
    public String getMessage()
    {
        StringBuilder bud = new StringBuilder();

        String code = exceptionBean.getCode();

        // 没有异常码或没有取到异常信息
        if (null == code || code.equals("common.unknown.error"))
        {
            // 如果errorMessage不为空,直接返回出错信息.
            if (exceptionBean.getMessage() != null)
            {
                bud.append(exceptionBean.getMessage());

                // 添加异常链中的信息
                if (getCause() != null)
                {
                    bud.append(" <-- ");
                    bud.append(getCause().getMessage());
                }

                return bud.toString();
            }
            // 设置未知错误的信息
            else
            {
                //bud.append(config.getString("common.unknown.error"));
                bud.append(ResourceManager.getValue("common.unknown.error"));

                // 添加异常链中的信息
                if (getCause() != null)
                {
                    bud.append(" <-- ");
                    bud.append(getCause().getMessage());
                }

                return bud.toString();
            }
        }
        else
        {
            // 用exceptionCode查询Properties文件获得出错信息
            try
            {
                //bud.append(config.getString(code));
                bud.append(ResourceManager.getValue(code));
            }
            //catch (MissingResourceException mse)
            catch(Exception mse)
            {
                bud.append(exceptionBean.getCode());
            }

            // 添加异常链中的信息
            if (getCause() != null)
            {
                bud.append(" <-- ");
                bud.append(getCause().getMessage());
            }

            // 将出错信息中的参数传入到出错信息中
            String message = bud.toString();
            if (exceptionBean.getParameters() != null)
            {
                message = MessageFormat.format(message, exceptionBean
                        .getParameters());
            }

            return message;
        }
    }

    /**
     * 获取异常信息
     * 
     * @return 返回相应的异常信息
     */
    public String getSimpleMessage()
    {
        StringBuilder bud = new StringBuilder();

        String code = exceptionBean.getCode();

        // 没有异常码或没有取到异常信息
        if (null == code || code.equals("common.unknown.error"))
        {
            // 如果errorMessage不为空,直接返回出错信息.
            if (exceptionBean.getMessage() != null)
            {
                bud.append(exceptionBean.getMessage());

                return bud.toString();
            }
            // 设置未知错误的信息
            else
            {
                //bud.append(config.getString("common.unknown.error"));
                bud.append(ResourceManager.getValue("common.unknown.error"));

                return bud.toString();
            }
        }
        else
        {
            // 用exceptionCode查询Properties文件获得出错信息
            try
            {
                //bud.append(config.getString(code));
                bud.append(ResourceManager.getValue(code));
            }
            //catch (MissingResourceException mse)
            catch(Exception mse)
            {
                bud.append(exceptionBean.getCode());
            }

            // 将出错信息中的参数传入到出错信息中
            String message = bud.toString();
            if (exceptionBean.getParameters() != null)
            {
                message = MessageFormat.format(message, exceptionBean
                        .getParameters());
            }

            return message;
        }
    }

    /**
     * 设置异常信息
     * 
     * @param msg
     *            异常信息，不提供国际化
     */
    public void setMessage(String msg)
    {
        exceptionBean.setMessage(msg);
    }

    /**
     * 获取异常
     * 
     * @return Throwable 异常
     */
    public Throwable getCause()
    {
        return this.nestedThrowable;
    }

    /**
     * 获取参数数组
     * 
     * @return 参数数组
     */
    public Object[] getParamers()
    {
        return exceptionBean.getParameters();
    }

    /**
     * 异常属性Bean
     */
    private static class ExceptionBean implements Serializable
    {
        /**
         * serialVersionUID
         */
        private static final long serialVersionUID = -8035309016877170717L;

        /**
         * 错误信息
         */
        private String message = "";

        /**
         * 错误码
         */
        private String code = ErrorCode.COMMON_UNKNOWN_ERROR;

        /**
         * 参数数组
         */
        private Object[] parameters = null;

        public String getMessage()
        {
            return message;
        }

        public void setMessage(String message)
        {
            this.message = message;
        }

        public String getCode()
        {
            return code;
        }

        public void setCode(String code)
        {
            this.code = code;
        }

        public Object[] getParameters()
        {
            return parameters;
        }

        public void setParameters(Object[] parameters)
        {
            this.parameters = parameters;
        }
    }
}
